function f_check_osc_or_alter()
{   #检查是使用alter还是osc进行改表
    declare fun_name
    fun_name="f_check_osc_or_alter"
    f_logging "REMAIND:${fun_name}" "本次操作将执行如下sql" >/dev/null
    cat ${alter_file_tmp2} >> ${log_file} || f_exit "1"
    for ((i=1;i<=$(wc -l < ${alter_file_tmp2});i++))
    do
        [ "${execute}x" == "1x" ] && script_start_time="$(date +%s)"  #改当前表开始时间, 记录这个时间是为了方便打印进度的时候作为判断依据, 只会将该表大于10min中的发邮件
        line="$(sed -n "${i}p" ${alter_file_tmp2}|sed "s/${var_str1}/;/g;s/${var_str2}/,/g")"
        _t_="$(awk '{print $3}' <<< ${line}|sed 's/`//g')"  #表名 , 不管是否是保留字都不会有反引号
        t_tmp="$(awk '{print $3}' <<< ${line})"           #表名 , 如果是保留字则会带上反引号
        is_has_table="$(f_exe_sql_in_mysql "select count(*) from ${isdbt} where TABLE_SCHEMA = '${mysql_db}' and TABLE_NAME='${_t_}';")"

        if [ "${is_has_table}x" == "0x" ]
        then
            grep -wi "${_t_}" ${alter_file_tmp2} || true
            __="根据提交的sql语句, 检查到 '${mysql_host}:${mysql_port}' 实例不存在库 '${mysql_db}' , 或者表 '${mysql_db}.${_t_}'"
            [ "${execute}x" != "1x" ] && exe_sql_get_error_info_list+=("${__}") && continue
            f_logging "ERROR:${fun_name}" "${__}" "2" "1"
        fi

        table_pk="select count(*) from ${isdbc} where TABLE_SCHEMA = '${mysql_db}' and TABLE_NAME='${_t_}'"
        table_pk="$(f_exe_sql_in_mysql "${table_pk} and ((COLUMN_KEY='UNI' and IS_NULLABLE = 'NO') or COLUMN_KEY='PRI');")"

        if [ "${table_pk}x" == "0x" ]
        then
            __="检查到 '${mysql_host}:${mysql_port}' 实例的表 '${mysql_db}.${t_tmp}' 没有主键或者非空的唯一索引, 请联系dba处理"
            [ "${execute}x" != "1x" ] && exe_sql_get_error_info_list+=("${__}") && continue
            f_logging "ERROR:${fun_name}" "${__}" "2" "1"
        fi

        f_check_ssh_auth "${mysql_host}" || f_exit "1"

        bug_mark_file="${script_execute_mark_dir}/bug.${mysql_host}.${mysql_port}.${mysql_db}.${_t_}"
        osc_run_mark_file="${script_execute_mark_dir}/mark.${mysql_host}.${mysql_port}.${mysql_db}.${_t_}" #这个文件名不能随便改, 要不然可能引起不必要的异常
        osc_run_mark_file_list+=("${osc_run_mark_file}")

        [ "${execute}x" == "0x" ] && f_support_onlineddl #检查是否符合onlineddl操作

        if [ "${check_slave_repl}x" == "allx" ]
        then
            for _mysql_slave_host_ in $(tr "," " " <<< "${mysql_slave_info[@]}")
            do #检查所有从库
                f_check_slave_status "${_mysql_slave_host_}"
            done
            unset _mysql_slave_host_
        else
            f_check_slave_status "${mysql_slave_host}"
        fi

        #检查mdl状态任务标志文件,存在就是任务还没完成
        check_mdl_mark_file="${script_execute_mark_dir}/f_check_mdl_lock_for_${mysql_host}_${mysql_port}_${mysql_db}_${_t_}_${_PPID}" 
        #检查连接数任务的标志文件,存在就是任务还没完成
        check_connect_file="${script_execute_mark_dir}/f_check_connect_for_${mysql_host}_${mysql_port}_${mysql_db}_${_t_}_${_PPID}"   
        check_thread_file="${script_execute_mark_dir}/f_check_thread_for_${mysql_host}_${mysql_port}_${mysql_db}_${_t_}_${_PPID}"   
        max_thread_file="${script_execute_mark_dir}/max_thread_for_${mysql_host}_${mysql_port}_${mysql_db}_${_t_}_${_PPID}"   
        [ ! -f "${check_connect_file}" ] && touch ${check_connect_file}
        f_check_connect "null" "30" "${check_tools}" "${mysql_db}" "${_t_}" "${mysql_user}" "connect" "连接数" >> ${log_file} && exe_state="${?}" || exe_state="${?}"
        [ -f "${check_connect_file}" ] && rm -f ${check_connect_file}

        if [ ${exe_state} -ne 0 ]
        then
            f_logging "ERROR:${fun_name}" "当前master节点 '${mysql_host}:${mysql_port}' 连接数持续30秒都大于限制的最大连接数 ${max_threads}, 改表终止" "2" "1"
        fi

        _show_osc_info_="master:'${mysql_host}' 与本机 '${localhost_ip}'"
        if [ "${fast_add_column}x" == "truex" ]
        then #如果是8.0
        #[ "$(grep -c "^8" <<< "${mysql_version}")x" == "1x" ] && [ "${check_line_ok}x" == "3x" ] && [ "${is_add_column}x" == "1x" ] && [ "${row_format}x" == "${1}x" ] && [ "${full_index}x" == "0x" ]
            f_logging "REMAIND:${fun_name}" "根据提交的sql, 本次操作将使用8.0新特性, 秒加字段" "execute:${execute}"
            f_exe_alter_sql || f_exit "1"
        elif [ "$(grep -c "^8" <<< "${mysql_version}")x" == "1x" ] && [ "${only_rename_key_or_col}x" == "0x" ] && [ "${rename_key_or_col}x" != "0x" ]
        then #全部是rename index|key|column操作
            f_logging "REMAIND:${fun_name}" "根据提交的sql, 本次操作将使用8.0新特性, 秒修改字段或者索引" "execute:${execute}"
            f_exe_alter_sql || f_exit "1"
        elif [ "$(grep -ic "^alter table ${t_tmp} rename to" <<< "${line}")x" == "1x" ]
        then #如果是rename table 就传一个新表名
            f_exe_alter_sql "$(sed 's/;//g' <<< "${line}"|awk '{print $NF}')" || f_exit "1"
        elif [ "${support_online_ddl}x" == "1x" ] && [ "${only_modify_comment_or_auto_inc}x" == "1x" ] || [ "${modify_column_support_onlineddl}x" == "1x" ]
        then #仅修改auto_increment的值, 修改注释
            f_exe_alter_sql || f_exit "1"
        elif [ "${change_col_count}x" != "0x" ]
        then #是否只有change
            f_check_change_sql "${only_change_col}" || f_exit "1"
        elif [ "${support_online_ddl}x" == "1x" ] && [ "${only_drop_index}x" == "0x" ] && [ "${drop_index_count}x" != "0x" ]
        then
            f_logging "REMAIND:${fun_name}" "根据提交的sql, 本次操作删除索引仅修改了元数据, 将使用online ddl特性."
            f_exe_alter_sql || f_exit "1"
	elif [ "${format_mark}x" == "1x" ] && [ "${idc_mark}x" == "1x" ]
        then #binlog格式是row且执行操作的机器与master在同城则使用ghost, 否则都使用pt
            __="${_show_osc_info_}, 网络延迟小于预设值" #临时变量
            if [ "${force_tool}x" == "0x" ] #如果用户使用了-C参数, 则使用pt工具进行改表, 反之根据原来的逻辑判断是否同机房及是否是行模式
            then
                f_logging "REMAIND:${fun_name}" "${__}, 且binlog_format=ROW, 但是用户使用了'-C 0', 强制使用pt来进行改表, 本次ddl使用pt来操作" "execute:${execute}"
                f_exe_osc_comm "pt-online-schema-change" || f_exit "1"
            else
                f_logging "REMAIND:${fun_name}" "${__}, 且binlog_format=ROW, 本次ddl使用ghost来操作" "execute:${execute}"
                f_exe_osc_comm "gh-ost" && exe_state="${?}" || exe_state="${?}"
                if [ -f "${bug_mark_file}" ] && [ ${exe_state} -eq 100 ]
                then #遇到bug, 本次操作尝试使用pt重新跑
                    rm -f "${bug_mark_file}"
                    f_logging "ERROR:${fun_name}" "使用ghost改表遇到bug, 本次操作尝试使用pt重新跑" "2"
                    sed -n "${i},\$p" ${alter_file_tmp2} > ${alter_file_tmp1} #这种情况, 需要将当前行到文件末尾记录下来
                    return 100
                elif [ ${exe_state} -ne 0 ]
                then
                    f_exit "1"
                fi
            fi
            unset __
	elif [ "${format_mark}x" == "1x" ]
        then #binlog格式是row, 但是执行操作的机器与master不在同城则使用pt
            f_logging "REMAIND:${fun_name}" "${_show_osc_info_}, 不属于同城, 本次ddl使用pt来操作" "execute:${execute}"
            f_exe_osc_comm "pt-online-schema-change" || f_exit "1"
        else
            __="${_show_osc_info_}, binlog_format 不是 'ROW'"
            f_logging "REMAIND:${fun_name}" "${__}, 本次ddl不满足使用ghost来操作, 将使用pt-osc来操作" "execute:${execute}"
            f_exe_osc_comm "pt-online-schema-change" || f_exit "1"
        fi
        [ ${i} -eq 5 -a "${execute}x" == "1x" ] && sed -n "6,\$p" ${alter_file_tmp2} > ${alter_file_tmp1} && return 100 #这种情况, 需要将当前行到文件末尾记录下来
    done

    if [ "${execute}x" != "1x" ] && [ "${#exe_sql_get_error_info_list[@]}x" != "0x" ]
    then
        f_logging "ERROR:${fun_name}" "执行提交的sql中, 存在如下错误 ] [ 详情请看日志 '${log_file}'"
        __="测试环境'${test_host}:${test_port}'执行失败" #临时变量, 供下面的for循环使用
        f_record_info_to_dbadb "test" "${_t_}" "测试环境执行失败. 详情请看${localhost_ip}:${log_file}" || true
    fi

    for ((sql_exe_error_count=0; sql_exe_error_count<${#exe_sql_get_error_info_list[@]}; sql_exe_error_count++))
    do
        f_logging "ERROR:${fun_name}" "${__} ] [ ${exe_sql_get_error_info_list[${sql_exe_error_count}]}"
    done
    
    if [ "${execute}x" != "1x" ] && [ "${#exe_sql_get_error_info_list[@]}x" == "0x" ]
    then
        if [ "${execute_opt}x" != "1x" ]
        then
            f_logging "WARN:${fun_name}" "测试环境执行通过, 如需在生产环境执行, 请在原来参数的基础上加 '-e 1' " "2"
        else
            f_logging "REMAIND:${fun_name}" "测试环境执行通过, 下面准备在生产环境执行"
        fi
    elif [ "${execute}x" != "1x" ] && [ "${#exe_sql_get_error_info_list[@]}x" != "0x" ]
    then
        f_logging "WARN:${fun_name}" "测试环境执行不通过, 请根据如上提示信息进行修改" "2" "1"
    elif [ "${execute}x" == "1x" ]
    then
        f_logging "INFO:${fun_name}" "本次操作完成, 所有任务均执行成功"
    fi
    return 0
}

